%%%-------------------------------------------------------------------
%%% @author chenlong
%%% @copyright (C) 2019, <COMPANY>
%%% @doc
%%%
%%% @end
%%% Created : 21. 三月 2019 11:36
%%%-------------------------------------------------------------------
-module(room_server).
-author("chenlong").

-behaviour(gen_server).

-include("common.hrl").

%% API
-export([start_link/1]).

%% gen_server callbacks
-export([init/1,
	handle_call/3,
	handle_cast/2,
	handle_info/2,
	terminate/2,
	code_change/3]).

-define(SERVER, ?MODULE).

-record(state, {}).

-export([leaveRoom/2, enterRoom/2]).

%%--------------------------------------------------------------------
%% @doc
%% Starts the server
%%
%% @end
%%--------------------------------------------------------------------
start_link(Arg) ->
	gen_server:start_link(?MODULE, Arg, []).

%%%===================================================================
%%% gen_server callbacks
%%%===================================================================

%%--------------------------------------------------------------------
%% @private
%% @doc
%% Initializes the server
%%
%% @spec init(Args) -> {ok, State} |
%%                     {ok, State, Timeout} |
%%                     ignore |
%%                     {stop, Reason}
%% @end
%%--------------------------------------------------------------------
-spec(init(Args :: term()) ->
	{ok, State :: #state{}} | {ok, State :: #state{}, timeout() | hibernate} |
	{stop, Reason :: term()} | ignore).
init({RoomID, _MasterID, _SettingList}) ->
	InitRoom = #room{
		roomID = RoomID
	},
	setRoom(InitRoom),
	timer_wheel:init(),
	?CATCH(erlang:register(util:roomRegName(RoomID), self())),
	ets:insert(?ETS_BATTLE, #ets_battle{roomID = RoomID}),
	Now = util:now(),
	timer_wheel:plan(Now + 1, fun secondsTick/1),
	{ok, #state{}}.

%%--------------------------------------------------------------------
%% @private
%% @doc
%% Handling call messages
%%
%% @end
%%--------------------------------------------------------------------
-spec(handle_call(Request :: term(), From :: {pid(), Tag :: term()},
	State :: #state{}) ->
	{reply, Reply :: term(), NewState :: #state{}} |
	{reply, Reply :: term(), NewState :: #state{}, timeout() | hibernate} |
	{noreply, NewState :: #state{}} |
	{noreply, NewState :: #state{}, timeout() | hibernate} |
	{stop, Reason :: term(), Reply :: term(), NewState :: #state{}} |
	{stop, Reason :: term(), NewState :: #state{}}).
handle_call(_Request, _From, State) ->
	{reply, ok, State}.

%%--------------------------------------------------------------------
%% @private
%% @doc
%% Handling cast messages
%%
%% @end
%%--------------------------------------------------------------------
-spec(handle_cast(Request :: term(), State :: #state{}) ->
	{noreply, NewState :: #state{}} |
	{noreply, NewState :: #state{}, timeout() | hibernate} |
	{stop, Reason :: term(), NewState :: #state{}}).
handle_cast({destroy}, State) ->
	#room{roomID = RoomID} = getRoom(),
	room_manager ! {roomDestroy, RoomID},
	{stop, normal, State};
handle_cast(_Request, State) ->
	{noreply, State}.

%%--------------------------------------------------------------------
%% @private
%% @doc
%% Handling all non call/cast messages
%%
%% @spec handle_info(Info, State) -> {noreply, State} |
%%                                   {noreply, State, Timeout} |
%%                                   {stop, Reason, State}
%% @end
%%--------------------------------------------------------------------
-spec(handle_info(Info :: timeout() | term(), State :: #state{}) ->
	{noreply, NewState :: #state{}} |
	{noreply, NewState :: #state{}, timeout() | hibernate} |
	{stop, Reason :: term(), NewState :: #state{}}).
handle_info({destroy}, State) ->
	#room{roomID = RoomID} = getRoom(),
	room_manager ! {roomDestroy, RoomID},
	{stop, normal, State};
handle_info(Info, State) ->
	try
		case Info of
			{?timer_wheel_tick, Sec} ->
				timer_wheel:work(Sec);
			%%-------房间相关--------
			{leaveRoom, RoleID} ->
				doLeaveRoom(RoleID);
			{enterRoom, RoleID} ->
				doEnterRoom(RoleID);
			{changePos, RoleID, TarPos} ->
				doChangePos(RoleID, TarPos);
			{roomKick, TarRoleID} ->
				doRoomKick(TarRoleID);
			{changeReady, RoleID} ->
				onChangeReady(RoleID);
			{fastJoin, RoleID, EtsRoomList} ->
				onFastJoin(RoleID, EtsRoomList);
			%%---------战斗相关-----------
			{battleUncover, RoleID, StationID} ->
				onBattleUncover(RoleID, StationID);
			{battleMove, RoleID, TarStationID, WithFlag} ->
				onBattleMove(RoleID, TarStationID, WithFlag);
			{battleSurrender, RoleID, Type} ->
				onBattleSurrender(RoleID, Type);
			{battleSurrenderAnswer, RoleID, IsAgree} ->
				onBattleSurrenderAnswer(RoleID,IsAgree);
			_ ->
				?ERR("no match module = ~p, Info=~p", [?MODULE, Info])
		end
	catch
		ok -> ok;
		_:Why:StackTrace ->
			?ERR("module=~p handle_info Info=~p,Why=~p,StackTrace=~p", [?MODULE, Info, Why, StackTrace])
	end,
	{noreply, State}.

%%--------------------------------------------------------------------
%% @private
%% @doc
%% This function is called by a gen_server when it is about to
%% terminate. It should be the opposite of Module:init/1 and do any
%% necessary cleaning up. When it returns, the gen_server terminates
%% with Reason. The return value is ignored.
%%
%% @spec terminate(Reason, State) -> void()
%% @end
%%--------------------------------------------------------------------
-spec(terminate(Reason :: (normal | shutdown | {shutdown, term()} | term()),
	State :: #state{}) -> term()).
terminate(_Reason, _State) ->
	#room{roomID = RoomID} = getRoom(),
	?CATCH(erlang:unregister(util:roomRegName(RoomID))),
	room_manager ! {roomDestroy, RoomID},
	ok.

%%--------------------------------------------------------------------
%% @private
%% @doc
%% Convert process state when code is changed
%%
%% @spec code_change(OldVsn, State, Extra) -> {ok, NewState}
%% @end
%%--------------------------------------------------------------------
-spec(code_change(OldVsn :: term() | {down, term()}, State :: #state{},
	Extra :: term()) ->
	{ok, NewState :: #state{}} | {error, Reason :: term()}).
code_change(_OldVsn, State, _Extra) ->
	{ok, State}.


%%%===================================================================
%%% API
%%%===================================================================
leaveRoom(RoomID, RoleID) ->
	try
		#ets_room{roomPID = RoomPID} = room_manager:getEtsRoom(RoomID),
		RoomPID ! {leaveRoom, RoleID}
	catch
		_:Why ->
			?ERR("leaveRoom Why=~p,RoomID=~p, RoleID=~p", [Why, RoomID, RoleID])
	end.

%%return boolean()
enterRoom(RoomID, RoleID) ->
	try
		#ets_room{roomPID = RoomPID} = room_manager:getEtsRoom(RoomID),
		RoomPID ! {enterRoom, RoleID},
		?TRUE
	catch
		_:Why ->
			?ERR("enterRoom Why=~p,RoomID=~p, RoleID=~p", [Why, RoomID, RoleID]),
			?FALSE
	end.

%%%===================================================================
%%% Internal functions
%%%===================================================================
doLeaveRoom(RoleID) ->
	#room{roomID = RoomID} = getRoom(),
	EtsRoom = room_manager:getEtsRoom(RoomID),
	%%自己是否在准备状态
	#room_player{state = _PlayerState, pos = Pos} = lists:keyfind(RoleID, #room_player.playerID, EtsRoom#ets_room.playerList),
%%	case PlayerState of
%%		?PLAYER_STATE_IDLE -> ok;
%%		_ ->
%%			role_lib:sendToClient(RoleID, #sc_room_leave{result = 1, playerID = RoleID}),
%%			throw(ok)
%%	end,
%%	%%是否在战斗中，而且自己是参战者
%%	case EtsRoom#ets_room.roomState of
%%		?ROOM_STATE_IDLE -> ok;
%%		_ ->
%%			case Pos > 2 of
%%				?TRUE -> ok;
%%				_ ->%%自己是参战者
%%					role_lib:sendToClient(RoleID, #sc_room_leave{result = 2, playerID = RoleID}),
%%					throw(ok)
%%			end
%%	end,
	%%执行退出房间逻辑
	%%是否是最后一个成员，是则销毁房间
	NewPlayerList = lists:keydelete(RoleID, #room_player.playerID, EtsRoom#ets_room.playerList),
	case length(NewPlayerList) =< 0 of
		?TRUE ->
			%%广播退出房间消息
			role_lib:broadcastToClient(EtsRoom, #sc_room_leave{result = 0, playerID = RoleID, pos = Pos}),
			%%回复玩家进程，退出房间
			role_lib:sendToPlayerServer(RoleID, {resLeaveRoom, RoomID}),
			%%销毁房间
			gen_server:cast(self(), {destroy});
		_ ->
			%%如果在对战中，则判断对方获胜，这里先判断，否则下面已经从playerList里面删除了
			%%是否在战斗中，而且自己是参战者
			case EtsRoom#ets_room.roomState of
				?ROOM_STATE_IDLE -> ok;
				_ ->
					case Pos > 2 of
						?TRUE -> ok;
						_ ->%%自己是参战者，则直接判断对方获胜
							onWin(battle_lib:changeTurnPos(Pos))
					end
			end,
			%%下面执行离开房间逻辑
			EtsRoom0 = EtsRoom#ets_room{playerList = NewPlayerList},
			%%自己是否是房主
			EtsRoom2 = case EtsRoom0#ets_room.masterID of
				           RoleID ->%%转交给其他人
					           #room_player{playerID = NewMasterID} = hd(NewPlayerList),
					           EtsRoom1 = EtsRoom0#ets_room{masterID = NewMasterID},
					           %%广播给其他人
					           role_lib:broadcastToClient(EtsRoom1, #sc_room_change_leader{result = 0, srcPlayerID = RoleID, tarPlayerID = NewMasterID}),
					           EtsRoom1;
				           _ -> EtsRoom0
			           end,
			%%广播退出房间消息
			role_lib:broadcastToClient(EtsRoom, #sc_room_leave{result = 0, playerID = RoleID, pos = Pos}),
			%%回写房间信息ETS
			ets:update_element(?ETS_ROOM, RoomID, [
				{#ets_room.playerList, EtsRoom2#ets_room.playerList},
				{#ets_room.masterID, EtsRoom2#ets_room.masterID}
			]),
			%%回复玩家进程，退出房间
			role_lib:sendToPlayerServer(RoleID, {resLeaveRoom, RoomID}),
			ok
	end.

doEnterRoom(RoleID) ->
	RoomID = getRoomID(),
	EtsRoom = room_manager:getEtsRoom(RoomID),
	%%检查是否已经满员
	case length(EtsRoom#ets_room.playerList) >= battle_lib:getMaxRoomPlayerCount() of
		?TRUE ->%%已经满员
			role_lib:sendToClient(RoleID, #sc_room_enter{result = 1});
		_ ->
			%%分配一个pos
			Fun = fun(Index) ->
				case Index =< 2 of
					?TRUE ->%%战斗位置要特殊判断，-1 -2的位置
						{lists:keymember(Index, #room_player.pos, EtsRoom#ets_room.playerList)
							orelse lists:keymember(-Index, #room_player.pos, EtsRoom#ets_room.playerList), Index};
					_ ->
						{lists:keymember(Index, #room_player.pos, EtsRoom#ets_room.playerList), Index}
				end
			      end,
			Pos = util:listFunReturn(Fun, ?FALSE, lists:seq(1, battle_lib:getMaxRoomPlayerCount()), 0),
			case Pos of
				0 ->%%分配POS失败
					?ERR("doEnterRoom pos error RoleID=~p,EtsRoom=~p", [RoleID, EtsRoom]),
					role_lib:sendToClient(RoleID, #sc_room_enter{result = 2});
				_ ->
					%%回写房间
					NewPlayerList = [#room_player{playerID = RoleID, pos = Pos} | EtsRoom#ets_room.playerList],
					EtsRoom1 = EtsRoom#ets_room{playerList = NewPlayerList},
					ets:update_element(?ETS_ROOM, RoomID, {#ets_room.playerList, EtsRoom1#ets_room.playerList}),
					role_lib:sendToPlayerServer(RoleID, {resEnterRoom, EtsRoom1})
			end
	end.

doChangePos(RoleID, TarPos) ->
	RoomID = getRoomID(),
	EtsRoom = room_manager:getEtsRoom(RoomID),
	%%是否是空位
	case lists:keymember(TarPos, #room_player.pos, EtsRoom#ets_room.playerList) of
		?TRUE ->%%已经有人
			role_lib:sendToClient(RoleID, #sc_room_change_pos{result = 1, playerID = RoleID, srcPos = 0, tarPos = 0}),
			throw(ok);
		_ -> ok
	end,
	{RoomPlayer, T} = case lists:keytake(RoleID, #room_player.playerID, EtsRoom#ets_room.playerList) of
		                  {value, RoomPlayer0, T0} -> {RoomPlayer0, T0};
		                  _ ->
			                  ?ERR("cs_room_change_pos cannot find player RoleID=~p,TarPos=~p,EtsRoom=~p", [RoleID, TarPos, EtsRoom]),
			                  throw(ok)
	                  end,
	%%自己是否在准备状态
	case RoomPlayer#room_player.state of
		?PLAYER_STATE_IDLE -> ok;
		_ ->
			role_lib:sendToClient(RoleID, #sc_room_change_pos{result = 2, playerID = RoleID, srcPos = 0, tarPos = 0}),
			throw(ok)
	end,
	%%是否在战斗状态
	case EtsRoom#ets_room.roomState of
		?ROOM_STATE_IDLE -> ok;
		_ ->
			role_lib:sendToClient(RoleID, #sc_room_change_pos{result = 3, playerID = RoleID, srcPos = 0, tarPos = 0}),
			throw(ok)
	end,
	%%修改位置
	EtsRoom1 = EtsRoom#ets_room{playerList = [RoomPlayer#room_player{pos = TarPos} | T]},
	ets:update_element(?ETS_ROOM, RoomID, {#ets_room.playerList, EtsRoom1#ets_room.playerList}),
	%%广播最新房友（位置）信息
	role_lib:broadcastToClient(EtsRoom1, #sc_room_member_list{memberList = role_room:makeMemberListMsg(EtsRoom1),roomState = EtsRoom1#ets_room.roomState}),
	%%广播修改
	role_lib:broadcastToClient(EtsRoom1, #sc_room_change_pos{result = 0, playerID = RoleID, srcPos = RoomPlayer#room_player.pos, tarPos = TarPos}),
	ok.

doRoomKick(TarRoleID) ->
	RoomID = getRoomID(),
	EtsRoom = room_manager:getEtsRoom(RoomID),
	%%是否在比赛中
	{TarRoomPlayer, T} = case lists:keytake(TarRoleID, #room_player.playerID, EtsRoom#ets_room.playerList) of
		                     {value, TarRoomPlayer0, T0} -> {TarRoomPlayer0, T0};
		                     _ ->%%已经离开了房间
			                     role_lib:sendToClient(EtsRoom#ets_room.masterID, #sc_room_kick{result = 0, playerID = TarRoleID,pos = 0}),
			                     throw(ok)
	                     end,
	case EtsRoom#ets_room.roomState of
		?ROOM_STATE_IDLE ->%%不是比赛，都可以踢
			ok;
		_ ->%%如果是比赛中则只能踢观战者
			case TarRoomPlayer#room_player.pos > 2 of
				?TRUE -> ok;
				_ ->
					role_lib:sendToClient(EtsRoom#ets_room.masterID, #sc_room_kick{result = 2, playerID = 0,pos = 0}),
					throw(ok)
			end
	end,
	%%回写 修改ETS字段
	ets:update_element(?ETS_ROOM, EtsRoom#ets_room.roomID, {#ets_room.playerList, T}),
	%%通知玩家进程，被踢出房间
	role_lib:sendToPlayerServer(TarRoleID, {roomKick}),
	%%广播玩家被踢，被踢玩家自己也接收消息，这样客户端收到消息退出房间
	role_lib:broadcastToClient(EtsRoom, #sc_room_kick{result = 0, playerID = TarRoleID,pos = TarRoomPlayer#room_player.pos}).

onChangeReady(RoleID) ->
	RoomID = getRoomID(),
	EtsRoom = room_manager:getEtsRoom(RoomID),
	{RoomPlayer, T} = case lists:keytake(RoleID, #room_player.playerID, EtsRoom#ets_room.playerList) of
		                  {value, RoomPlayer0, T0} -> {RoomPlayer0, T0};
		                  _ ->
			                  ?ERR("onChangeReady cannot find player RoleID=~p,EtsRoom=~p", [RoleID, EtsRoom]),
			                  throw(ok)
	                  end,
	%%是否在战斗位置
	case RoomPlayer#room_player.pos =< 2 of
		?TRUE -> ok;
		_ ->%%不在战斗位置，无法修改
			role_lib:sendToClient(RoleID, #sc_room_change_ready{result = 1, playerID = 0, readyState = 0}),
			throw(ok)
	end,
	%%是否已经开始战斗
	case EtsRoom#ets_room.roomState of
		?ROOM_STATE_IDLE -> ok;
		_ ->
			role_lib:sendToClient(RoleID, #sc_room_change_ready{result = 2, playerID = 0, readyState = 0}),
			throw(ok)
	end,
	NewState = ?IF(RoomPlayer#room_player.state =:= ?PLAYER_STATE_IDLE, ?PLAYER_STATE_READY, ?PLAYER_STATE_IDLE),
	%%修改ETS字段
	RoomPlayerList1 = [RoomPlayer#room_player{state = NewState} | T],
	ets:update_element(?ETS_ROOM, RoomID, {#ets_room.playerList, RoomPlayerList1}),
	%%广播消息
	role_lib:broadcastToClient(EtsRoom, #sc_room_change_ready{result = 0, playerID = RoleID, readyState = NewState}),
	%%检测是否开始战斗
	case checkFightBegin() of
		?FALSE -> ok;
		_ ->
			role_lib:broadcastToClient(EtsRoom, #sc_battle_begin{}),
			%%将两个战斗玩家位置修改为负数，状态修改为空闲
			RoomPlayerList2 = lists:map(
				fun(#room_player{pos = Pos} = RP) ->
					?IF(Pos =< 2, RP#room_player{pos = -abs(Pos),state = ?PLAYER_STATE_IDLE}, RP)
				end, RoomPlayerList1),
			ets:update_element(?ETS_ROOM, RoomID, [
				{#ets_room.roomState, ?ROOM_STATE_BATTLE},
				{#ets_room.playerList, RoomPlayerList2}
			]),
			InitPos = util:random_int(1, 2),
			TurnEndTime = util:now() + battle_lib:getCfgBattle(turn_time, 30),
			InitEtsBattle = initEtsBattle(RoomID, InitPos, TurnEndTime),
			ets:insert(?ETS_BATTLE, InitEtsBattle),
			role_lib:broadcastToClient(EtsRoom, #sc_battle_turn{pos = InitPos, turnEndTime = TurnEndTime}),
			%%广播战斗状态
			MsgBattle = battle_lib:makeBattleInfoMsg(InitEtsBattle),
			role_lib:broadcastToClient(EtsRoom,MsgBattle),
			ok
	end,
	ok.

onFastJoin(RoleID, EtsRoomList) ->
	RoomID = getRoomID(),
	EtsRoom = room_manager:getEtsRoom(RoomID),
	%%检查是否已经满员
	EnterResult = case length(EtsRoom#ets_room.playerList) >= battle_lib:getMaxRoomPlayerCount() of
		?TRUE ->%%已经满员
			1;
		_ ->
			%%分配一个pos
			Fun = fun(Index) ->
				case Index =< 2 of
					?TRUE ->%%战斗位置要特殊判断，-1 -2的位置
						{lists:keymember(Index, #room_player.pos, EtsRoom#ets_room.playerList)
							orelse lists:keymember(-Index, #room_player.pos, EtsRoom#ets_room.playerList), Index};
					_ ->
						{lists:keymember(Index, #room_player.pos, EtsRoom#ets_room.playerList), Index}
				end
			      end,
			Pos = util:listFunReturn(Fun, ?FALSE, lists:seq(1, battle_lib:getMaxRoomPlayerCount()), 0),
			case Pos of
				0 ->%%分配POS失败
					?ERR("doEnterRoom pos error RoleID=~p,EtsRoom=~p", [RoleID, EtsRoom]),
					2;
				_ ->
					role_lib:sendToClient(RoleID,#sc_room_fast_join{result = 0}),
					%%回写房间
					NewPlayerList = [#room_player{playerID = RoleID, pos = Pos} | EtsRoom#ets_room.playerList],
					EtsRoom1 = EtsRoom#ets_room{playerList = NewPlayerList},
					ets:update_element(?ETS_ROOM, RoomID, {#ets_room.playerList, EtsRoom1#ets_room.playerList}),
					role_lib:sendToPlayerServer(RoleID, {resEnterRoom, EtsRoom1}),
					0
			end
	end,
	case EnterResult of
		0 ->%%进入成功
			ok;
		_ ->%%查看能否寻找下一个房间
			case EtsRoomList of
				[#ets_room{roomPID = RoomPID}|T] ->
					%%给筛选出来的房间进程，依据列表顺序依次判断真正能进入哪个房间
					RoomPID ! {fastJoin, RoleID, T};
				_ ->
					role_lib:sendToClient(RoleID,#sc_room_fast_join{result = 1})
			end
	end.

%%===============战斗相关=====================
onBattleUncover(RoleID, StationID) ->
	%%兵站是否合法
	case battle_lib:getCfgStation(StationID) of
		?UNDEFINED ->
			?DEBUG("error StationID=~p",[StationID]),
			throw(ok);
		_ -> ok
	end,
	RoomID = getRoomID(),
	EtsRoom = room_manager:getEtsRoom(RoomID),
	%%是否有房间
	%%是否在对战中
	case EtsRoom#ets_room.roomState of
		?ROOM_STATE_BATTLE -> ok;
		_ ->
			role_lib:sendToClient(RoleID, #sc_battle_uncover{result = 1, pos = 0, stationID = 0, pieceID = 0}),
			throw(ok)
	end,
	%%自己是否是战斗位置
	#room_player{pos = Pos} = lists:keyfind(RoleID, #room_player.playerID, EtsRoom#ets_room.playerList),
	case Pos =< 2 of
		?TRUE -> ok;
		_ ->
			?DEBUG("not battle pos = ~p",[Pos]),
			throw(ok)
	end,
	EtsBattle = room_manager:getEtsBattle(RoomID),
	%%是否是回合方
	case EtsBattle#ets_battle.turnPos of
		Pos -> ok;
		_ ->
			role_lib:sendToClient(RoleID, #sc_battle_uncover{result = 3, pos = 0, stationID = 0, pieceID = 0}),
			throw(ok)
	end,
	%%查看当前兵站信息，是否已经翻开
	Station = lists:keyfind(StationID, #station.stationID, EtsBattle#ets_battle.stationList),
	case Station#station.pieceID of
		?UNCOVER_PIECE_ID -> ok;
		_ ->
			role_lib:sendToClient(RoleID, #sc_battle_uncover{result = 4, pos = 0, stationID = 0, pieceID = 0}),
			throw(ok)
	end,
	%%执行翻开，切换回合方
	TurnPos1 = battle_lib:changeTurnPos(EtsBattle#ets_battle.turnPos),
	%%解除回合方 记录的上回合系统自动切换（如果有）
	LastTurnTimeOut1 = setelement(abs(Pos),EtsBattle#ets_battle.lastTurnTimeOut,?FALSE),
	IsLastTurnTimeOut = element(abs(TurnPos1),LastTurnTimeOut1),
	TurnEndTime1 = case IsLastTurnTimeOut of
		               ?TRUE -> util:now() + battle_lib:getCfgBattle(punish_turn_time, 15);
		               _ -> util:now() + battle_lib:getCfgBattle(turn_time, 30)
	               end,
	PieceID = util:random_one_from_list(EtsBattle#ets_battle.pieceIDList),
	Station1 = Station#station{pieceID = PieceID},
	StationList1 = lists:keyreplace(StationID, #station.stationID, EtsBattle#ets_battle.stationList, Station1),
	ets:update_element(?ETS_BATTLE, RoomID, [
		{#ets_battle.turnPos, TurnPos1},
		{#ets_battle.turnEndTime, TurnEndTime1},
		{#ets_battle.stationID, 0},
		{#ets_battle.pieceIDList, lists:delete(PieceID, EtsBattle#ets_battle.pieceIDList)},
		{#ets_battle.stationList, StationList1},
		{#ets_battle.lastTurnTimeOut,LastTurnTimeOut1}
	]),
	%%广播
	role_lib:broadcastToClient(EtsRoom, #sc_battle_uncover{result = 0, pos = abs(Pos), stationID = StationID, pieceID = PieceID}),

	%%这里要判断，因为翻棋是否得出了各自的红蓝方
	case Pos < 0 of
		?TRUE ->%% 还未决定出红蓝方
			CurPiecePos = battle_lib:getPosByPieceID(PieceID),
			case EtsBattle#ets_battle.lastPiecePos =< 0 of
				?TRUE ->%%第一次翻棋
					ets:update_element(?ETS_BATTLE,RoomID,{#ets_battle.lastPiecePos,CurPiecePos});
				_ ->
					case CurPiecePos =/= EtsBattle#ets_battle.lastPiecePos of
						?TRUE ->%%得出结果
							RoomPlayerList = EtsRoom#ets_room.playerList,
							RoomPlayerList1 = util:listKeyReplaceElement(Pos,#room_player.pos,RoomPlayerList,#room_player.pos,CurPiecePos),
							RoomPlayerList2 = util:listKeyReplaceElement(TurnPos1,#room_player.pos,RoomPlayerList1,#room_player.pos,EtsBattle#ets_battle.lastPiecePos),
							%%将pos修正为正数
							ets:update_element(?ETS_ROOM,RoomID,{#ets_room.playerList,RoomPlayerList2}),
							%%如果这里得出 双方切换了红蓝方，则需要翻转棋盘数据
							case CurPiecePos =/= abs(Pos) of
								?TRUE ->%%需要翻转棋盘
									StationList2 = battle_lib:reverseStations(StationList1),
									%%需要调换用位置记录的数据
									ets:update_element(?ETS_BATTLE,RoomID,[
										{#ets_battle.turnPos,EtsBattle#ets_battle.lastPiecePos},
										{#ets_battle.stationList, StationList2},
										{#ets_battle.systemTurnCount,util:reverseTuple(EtsBattle#ets_battle.systemTurnCount)},
										{#ets_battle.lastTurnTimeOut,util:reverseTuple(LastTurnTimeOut1)}
									]),
									ok;
								_ ->
									ets:update_element(?ETS_BATTLE,RoomID,[
										{#ets_battle.turnPos,EtsBattle#ets_battle.lastPiecePos}
									]),
									ok
							end,
							%%广播两个阵营的玩家ID，以此消息来决定显示颜色
							#room_player{playerID = PlayerID1}=lists:keyfind(1,#room_player.pos,RoomPlayerList2),
							#room_player{playerID = PlayerID2}=lists:keyfind(2,#room_player.pos,RoomPlayerList2),
							MsgCamp = #sc_battle_camp{playerID1 = PlayerID1,playerID2 = PlayerID2},
							role_lib:broadcastToClient(EtsRoom,MsgCamp),
							%%推送房间信息，主要是更正位置，客户端依据信息进行棋盘翻转
							MsgRoomShort = role_room:makeRoomShortMsg(room_manager:getEtsRoom(RoomID)),
							role_lib:broadcastToClient(EtsRoom,MsgRoomShort),
							%%推送战斗信息，主要是更正棋盘信息
							MsgBattle = battle_lib:makeBattleInfoMsg(room_manager:getEtsBattle(RoomID)),
							role_lib:broadcastToClient(EtsRoom,MsgBattle);
						_ -> ok
					end
			end;
		_ -> ok
	end,
	FinalTurnPos = util:getEtsElement(?ETS_BATTLE,RoomID,#ets_battle.turnPos,TurnPos1),
	FinalTurnEndTime = TurnEndTime1,
	role_lib:broadcastToClient(EtsRoom, #sc_battle_turn{pos = abs(FinalTurnPos), turnEndTime = FinalTurnEndTime}),
	ok.

onBattleMove(RoleID, TarStationID, WithFlag) ->
	%%兵站是否合法
	case battle_lib:getCfgStation(TarStationID) of
		?UNDEFINED ->
			?DEBUG("error TarStationID=~p",[TarStationID]),
			throw(ok);
		_ -> ok
	end,
	RoomID = getRoomID(),
	EtsRoom = room_manager:getEtsRoom(RoomID),
	%%是否有房间
	%%是否在对战中
	case EtsRoom#ets_room.roomState of
		?ROOM_STATE_BATTLE -> ok;
		_ ->
			role_lib:sendToClient(RoleID, #sc_battle_move{result = 1, moveResult = 0, pos = 0, srcStationID = 0, tarStationID = 0,idList = []}),
			throw(ok)
	end,
	%%自己是否是战斗位置
	#room_player{pos = Pos} = lists:keyfind(RoleID, #room_player.playerID, EtsRoom#ets_room.playerList),
	case Pos =< 2 of
		?TRUE -> ok;
		_ ->
			role_lib:sendToClient(RoleID, #sc_battle_move{result = 2, moveResult = 0, pos = 0, srcStationID = 0, tarStationID = 0,idList = []}),
			throw(ok)
	end,
	EtsBattle = room_manager:getEtsBattle(RoomID),
	%%是否是回合方
	case EtsBattle#ets_battle.turnPos of
		Pos -> ok;
		_ ->
			role_lib:sendToClient(RoleID, #sc_battle_move{result = 3, moveResult = 0, pos = 0, srcStationID = 0, tarStationID = 0,idList = []}),
			throw(ok)
	end,
	%%是否有上次兵站信息
	case EtsBattle#ets_battle.stationID of
		0 ->
			?DEBUG("lastStationID = 0"),
			throw(ok);
		_ -> ok
	end,
	%%上次兵站信息是否是己方
	#station{stationID = LastStationID, pieceID = LastPieceID} = lists:keyfind(EtsBattle#ets_battle.stationID, #station.stationID, EtsBattle#ets_battle.stationList),
	LastPos = battle_lib:getPosByPieceID(LastPieceID),
	case LastPos of
		Pos -> ok;
		_ ->
			?DEBUG("LastPos=~p,Pos=~p",[LastPos,Pos]),
			throw(ok)
	end,
	%%判断是否能移动过去
	{MoveResult,PassIDList} = battle_lib:stationToStation(LastStationID, TarStationID, EtsBattle, EtsRoom#ets_room.settingList),
	case battle_lib:canMoveByResult(MoveResult) of
		?TRUE ->
			%%执行移动（吃棋子）
			EtsBattle1 = onMoveResult(MoveResult, LastStationID, TarStationID, WithFlag, EtsBattle),
			%%广播移动
			role_lib:broadcastToClient(EtsRoom, #sc_battle_move{result = 0, moveResult = MoveResult, pos = Pos, srcStationID = LastStationID, tarStationID = TarStationID,idList = PassIDList}),
			case battle_lib:isPieceDeadByResult(MoveResult) of
				?TRUE ->
					role_lib:broadcastToClient(EtsRoom,#sc_battle_piece_dead{pieceIDList = [DeadPieceID||#dead{pieceID = DeadPieceID}<-element(1,EtsBattle1#ets_battle.deadList)++element(2,EtsBattle1#ets_battle.deadList)]});
				_ -> ok
			end,
			%%检测是否胜利
			case checkWin(EtsBattle1) of
				?FALSE ->
					%%切换回合方
					TurnPos1 = battle_lib:changeTurnPos(Pos),
					%%解除回合方 记录的上回合系统自动切换（如果有）
					LastTurnTimeOut1 = setelement(abs(Pos),EtsBattle1#ets_battle.lastTurnTimeOut,?FALSE),
					IsLastTurnTimeOut = element(abs(TurnPos1),LastTurnTimeOut1),
					TurnEndTime1 = case IsLastTurnTimeOut of
						?TRUE -> util:now() + battle_lib:getCfgBattle(punish_turn_time, 15);
						_ -> util:now() + battle_lib:getCfgBattle(turn_time, 30)
					end,
					ets:update_element(?ETS_BATTLE, RoomID, [
						{#ets_battle.turnPos, TurnPos1},
						{#ets_battle.turnEndTime, TurnEndTime1},
						{#ets_battle.stationID, 0},
						{#ets_battle.lastTurnTimeOut,LastTurnTimeOut1}
					]),
					%%广播
					role_lib:broadcastToClient(EtsRoom, #sc_battle_turn{pos = abs(TurnPos1), turnEndTime = TurnEndTime1}),
					ok;
				WinPos ->
					onWin(WinPos),
					ok
			end;
		_ ->
			role_lib:sendToClient(RoleID, #sc_battle_move{result = 4, moveResult = MoveResult, pos = 0, srcStationID = 0, tarStationID = 0,idList = []})
	end.

onBattleSurrender(RoleID, Type) ->
	RoomID = getRoomID(),
	EtsRoom = room_manager:getEtsRoom(RoomID),
	%%是否在对战中
	case EtsRoom#ets_room.roomState of
		?ROOM_STATE_BATTLE -> ok;
		_ ->
			role_lib:sendToClient(RoleID, #sc_battle_surrender{result = 1,cdTime = 0,pos = 0,type = Type}),
			throw(ok)
	end,
	%%自己是否是战斗位置
	#room_player{pos = Pos}=lists:keyfind(RoleID,#room_player.playerID,EtsRoom#ets_room.playerList),
	case Pos =< 2 of
		?TRUE -> ok;
		_ ->
			role_lib:sendToClient(RoleID, #sc_battle_surrender{result = 2,cdTime = 0,pos = 0,type = Type}),
			throw(ok)
	end,
	%%如果是投降，则直接游戏结束
	case Type of
		?SURRENDER_TYPE_GIVEUP ->
			onWin(battle_lib:changeTurnPos(Pos)),
			%%广播信息
			role_lib:broadcastToClient(EtsRoom,#sc_battle_surrender{result = 0, cdTime = 0, pos = abs(Pos), type = Type});
		_ ->
			%%记录投降、求和信息
			ets:update_element(?ETS_BATTLE,RoomID,{#ets_battle.surrender,{Pos,Type,util:now()}}),
			%%广播信息
			role_lib:broadcastToClient(EtsRoom,#sc_battle_surrender{result = 0, cdTime = 0, pos = abs(Pos), type = Type})
	end,
	ok.

onBattleSurrenderAnswer(RoleID,IsAgree) ->
	RoomID = getRoomID(),
	EtsRoom = room_manager:getEtsRoom(RoomID),
	%%是否有房间
	%%是否在对战中
	case EtsRoom#ets_room.roomState of
		?ROOM_STATE_BATTLE -> ok;
		_ ->
			role_lib:sendToClient(RoleID, #sc_battle_surrender_answer{result = 1}),
			throw(ok)
	end,
	%%自己是否是战斗位置
	#room_player{pos = Pos}=lists:keyfind(RoleID,#room_player.playerID,EtsRoom#ets_room.playerList),
	case Pos =< 2 of
		?TRUE -> ok;
		_ ->
			role_lib:sendToClient(RoleID, #sc_battle_surrender_answer{result = 2}),
			throw(ok)
	end,
	%%如果不同意，则直接忽略
	case IsAgree of
		0 ->
			role_lib:sendToClient(RoleID, #sc_battle_surrender_answer{result = 0}),
			throw(ok);
		_ -> ok
	end,
	%%是否有对方投降记录
	EtsBattle = room_manager:getEtsBattle(RoomID),
	case EtsBattle#ets_battle.surrender of
		{OtherPos, _Type, _Time} ->
			case OtherPos of
				Pos -> throw(ok);
				_ -> ok
			end;
		_ -> throw(ok)
	end,
	role_lib:sendToClient(RoleID, #sc_battle_surrender_answer{result = 0}),
	%%执行同意投降、求和
	SurrenderType = element(2,EtsBattle#ets_battle.surrender),
	case SurrenderType of
		?SURRENDER_TYPE_GIVEUP ->
			onWin(Pos);
		?SURRENDER_TYPE_PEACE ->
			onWin(0)
	end.

%%------------------------------INNER FUNCTION----------------------------------
getRoom() ->
	get(?ROOM_ROOM).
setRoom(Room) ->
	put(?ROOM_ROOM, Room).
getRoomID() ->
	#room{roomID = RoomID} = getRoom(),
	RoomID.

%%检测是否开始战斗
checkFightBegin() ->
	RoomID = getRoomID(),
	#ets_room{playerList = PlayerList} = room_manager:getEtsRoom(RoomID),
	case lists:keyfind(1, #room_player.pos, PlayerList) of
		#room_player{state = ?PLAYER_STATE_READY} ->
			case lists:keyfind(2, #room_player.pos, PlayerList) of
				#room_player{state = ?PLAYER_STATE_READY} -> ?TRUE;
				_ -> ?FALSE
			end;
		_ -> ?FALSE
	end.

%%return NewEtaBattle
%%空地直接移动
onMoveResult(0, SrcStationID, TarStationID, WithFlag, EtsBattle) ->
	#station{flagPieceList = SrcFlagList, pieceID = SrcPieceID} = SrcStation = lists:keyfind(SrcStationID, #station.stationID, EtsBattle#ets_battle.stationList),
	#station{flagPieceList = TarFlagList} = TarStation = lists:keyfind(TarStationID, #station.stationID, EtsBattle#ets_battle.stationList),
	case SrcFlagList of
		[FlagID1 | T] ->%%原位置有军旗
			case WithFlag of
				?TRUE ->%%移动军旗
					StationList1 = lists:keyreplace(SrcStationID, #station.stationID, EtsBattle#ets_battle.stationList, SrcStation#station{pieceID = 0, flagPieceList = []}),
					StationList2 = lists:keyreplace(TarStationID, #station.stationID, StationList1, TarStation#station{pieceID = SrcPieceID, flagPieceList = SrcFlagList ++ TarFlagList}),
					ets:update_element(?ETS_BATTLE, EtsBattle#ets_battle.roomID, {#ets_battle.stationList, StationList2}),
					EtsBattle#ets_battle{stationList = StationList2};
				_ ->%%不移动军旗
					%%将原位置军旗放到PieceID，如果有两个军旗，则放置一个军旗在上面
					StationList1 = lists:keyreplace(SrcStationID, #station.stationID, EtsBattle#ets_battle.stationList, SrcStation#station{pieceID = FlagID1, flagPieceList = T}),
					StationList2 = lists:keyreplace(TarStationID, #station.stationID, StationList1, TarStation#station{pieceID = SrcPieceID}),
					ets:update_element(?ETS_BATTLE, EtsBattle#ets_battle.roomID, {#ets_battle.stationList, StationList2}),
					EtsBattle#ets_battle{stationList = StationList2}
			end;
		_ ->%%没有军旗
			StationList1 = lists:keyreplace(SrcStationID, #station.stationID, EtsBattle#ets_battle.stationList, SrcStation#station{pieceID = 0}),
			StationList2 = lists:keyreplace(TarStationID, #station.stationID, StationList1, TarStation#station{pieceID = SrcPieceID}),
			ets:update_element(?ETS_BATTLE, EtsBattle#ets_battle.roomID, {#ets_battle.stationList, StationList2}),
			EtsBattle#ets_battle{stationList = StationList2}
	end;
%%吃掉对方
onMoveResult(1, SrcStationID, TarStationID, _WithFlag, EtsBattle) ->
	#station{flagPieceList = SrcFlagList, pieceID = SrcPieceID} = SrcStation = lists:keyfind(SrcStationID, #station.stationID, EtsBattle#ets_battle.stationList),
	#station{flagPieceList = _TarFlagList, pieceID = TarPieceID} = TarStation = lists:keyfind(TarStationID, #station.stationID, EtsBattle#ets_battle.stationList),
	TarPos = battle_lib:getPosByPieceID(TarPieceID),
	case SrcFlagList of
		[FlagID1 | T] ->%%原位置有军旗，默认 吃人不能移动军旗
			%%将原位置军旗放到PieceID，如果有两个军旗，则放置一个军旗在上面
			StationList1 = lists:keyreplace(SrcStationID, #station.stationID, EtsBattle#ets_battle.stationList, SrcStation#station{pieceID = FlagID1, flagPieceList = T}),
			StationList2 = lists:keyreplace(TarStationID, #station.stationID, StationList1, TarStation#station{pieceID = SrcPieceID}),
			TarDeadList = element(TarPos, EtsBattle#ets_battle.deadList),
			TarDeadList1 = [#dead{pieceID = TarPieceID, byPieceID = SrcPieceID} | TarDeadList],
			DeadList1 = setelement(TarPos, EtsBattle#ets_battle.deadList, TarDeadList1),
			ets:update_element(?ETS_BATTLE, EtsBattle#ets_battle.roomID, [
				{#ets_battle.stationList, StationList2},
				{#ets_battle.deadList, DeadList1}
			]),
			EtsBattle#ets_battle{stationList = StationList2, deadList = DeadList1};
		_ ->%%没有军旗
			StationList1 = lists:keyreplace(SrcStationID, #station.stationID, EtsBattle#ets_battle.stationList, SrcStation#station{pieceID = 0}),
			StationList2 = lists:keyreplace(TarStationID, #station.stationID, StationList1, TarStation#station{pieceID = SrcPieceID}),
			TarDeadList = element(TarPos, EtsBattle#ets_battle.deadList),
			TarDeadList1 = [#dead{pieceID = TarPieceID, byPieceID = SrcPieceID} | TarDeadList],
			DeadList1 = setelement(TarPos, EtsBattle#ets_battle.deadList, TarDeadList1),
			ets:update_element(?ETS_BATTLE, EtsBattle#ets_battle.roomID, [
				{#ets_battle.stationList, StationList2},
				{#ets_battle.deadList, DeadList1}
			]),
			EtsBattle#ets_battle{stationList = StationList2, deadList = DeadList1}
	end;
%%双方对掉
onMoveResult(2, SrcStationID, TarStationID, _WithFlag, EtsBattle) ->
	#station{flagPieceList = SrcFlagList, pieceID = SrcPieceID} = SrcStation = lists:keyfind(SrcStationID, #station.stationID, EtsBattle#ets_battle.stationList),
	#station{flagPieceList = TarFlagList, pieceID = TarPieceID} = TarStation = lists:keyfind(TarStationID, #station.stationID, EtsBattle#ets_battle.stationList),
	SrcPos = battle_lib:getPosByPieceID(SrcPieceID),
	TarPos = battle_lib:getPosByPieceID(TarPieceID),
	case SrcFlagList of
		[FlagID1 | T] ->%%原位置有军旗，对掉后，军旗留此地
			%%将原位置军旗放到PieceID，如果有两个军旗，则放置一个军旗在上面
			StationList1 = lists:keyreplace(SrcStationID, #station.stationID, EtsBattle#ets_battle.stationList, SrcStation#station{pieceID = FlagID1, flagPieceList = T}),
			%%对方是否有军旗
			StationList2 = case TarFlagList of
				               [FlagID2 | T2] ->%%对方有军旗
					               lists:keyreplace(TarStationID, #station.stationID, StationList1, TarStation#station{pieceID = FlagID2, flagPieceList = T2});
				               _ ->
					               lists:keyreplace(TarStationID, #station.stationID, StationList1, TarStation#station{pieceID = 0})
			               end,
			SrcDeadList = element(SrcPos, EtsBattle#ets_battle.deadList),
			SrcDeadList1 = [#dead{pieceID = SrcPieceID, byPieceID = TarPieceID} | SrcDeadList],
			TarDeadList = element(TarPos, EtsBattle#ets_battle.deadList),
			TarDeadList1 = [#dead{pieceID = TarPieceID, byPieceID = SrcPieceID} | TarDeadList],
			DeadList1 = setelement(SrcPos, EtsBattle#ets_battle.deadList, SrcDeadList1),
			DeadList2 = setelement(TarPos, DeadList1, TarDeadList1),
			ets:update_element(?ETS_BATTLE, EtsBattle#ets_battle.roomID, [
				{#ets_battle.stationList, StationList2},
				{#ets_battle.deadList, DeadList2}
			]),
			EtsBattle#ets_battle{stationList = StationList2, deadList = DeadList2};
		_ ->%%没有军旗
			StationList1 = lists:keyreplace(SrcStationID, #station.stationID, EtsBattle#ets_battle.stationList, SrcStation#station{pieceID = 0}),
			%%对方是否有军旗
			StationList2 = case TarFlagList of
				               [FlagID2 | T2] ->%%对方有军旗
					               lists:keyreplace(TarStationID, #station.stationID, StationList1, TarStation#station{pieceID = FlagID2, flagPieceList = T2});
				               _ ->
					               lists:keyreplace(TarStationID, #station.stationID, StationList1, TarStation#station{pieceID = 0})
			               end,
			SrcDeadList = element(SrcPos, EtsBattle#ets_battle.deadList),
			SrcDeadList1 = [#dead{pieceID = SrcPieceID, byPieceID = TarPieceID} | SrcDeadList],
			TarDeadList = element(TarPos, EtsBattle#ets_battle.deadList),
			TarDeadList1 = [#dead{pieceID = TarPieceID, byPieceID = SrcPieceID} | TarDeadList],
			DeadList1 = setelement(SrcPos, EtsBattle#ets_battle.deadList, SrcDeadList1),
			DeadList2 = setelement(TarPos, DeadList1, TarDeadList1),
			ets:update_element(?ETS_BATTLE, EtsBattle#ets_battle.roomID, [
				{#ets_battle.stationList, StationList2},
				{#ets_battle.deadList, DeadList2}
			]),
			EtsBattle#ets_battle{stationList = StationList2, deadList = DeadList2}
	end;
%%上军旗
onMoveResult(6, SrcStationID, TarStationID, WithFlag, EtsBattle) ->
	#station{flagPieceList = SrcFlagList, pieceID = SrcPieceID} = SrcStation = lists:keyfind(SrcStationID, #station.stationID, EtsBattle#ets_battle.stationList),
	#station{flagPieceList = TarFlagList, pieceID = TarPieceID} = TarStation = lists:keyfind(TarStationID, #station.stationID, EtsBattle#ets_battle.stationList),
	case SrcFlagList of
		[FlagID1 | T] ->%%原位置有军旗
			case WithFlag of
				?TRUE ->%%移动军旗
					StationList1 = lists:keyreplace(SrcStationID, #station.stationID, EtsBattle#ets_battle.stationList, SrcStation#station{pieceID = 0, flagPieceList = []}),
					StationList2 = lists:keyreplace(TarStationID, #station.stationID, StationList1, TarStation#station{pieceID = SrcPieceID, flagPieceList = [TarPieceID] ++ SrcFlagList ++ TarFlagList}),
					ets:update_element(?ETS_BATTLE, EtsBattle#ets_battle.roomID, {#ets_battle.stationList, StationList2}),
					EtsBattle#ets_battle{stationList = StationList2};
				_ ->%%不移动军旗
					%%将原位置军旗放到PieceID，如果有两个军旗，则放置一个军旗在上面
					StationList1 = lists:keyreplace(SrcStationID, #station.stationID, EtsBattle#ets_battle.stationList, SrcStation#station{pieceID = FlagID1, flagPieceList = T}),
					StationList2 = lists:keyreplace(TarStationID, #station.stationID, StationList1, TarStation#station{pieceID = SrcPieceID, flagPieceList = [TarPieceID | TarFlagList]}),
					ets:update_element(?ETS_BATTLE, EtsBattle#ets_battle.roomID, {#ets_battle.stationList, StationList2}),
					EtsBattle#ets_battle{stationList = StationList2}
			end;
		_ ->%%没有军旗
			StationList1 = lists:keyreplace(SrcStationID, #station.stationID, EtsBattle#ets_battle.stationList, SrcStation#station{pieceID = 0}),
			StationList2 = lists:keyreplace(TarStationID, #station.stationID, StationList1, TarStation#station{pieceID = SrcPieceID, flagPieceList = [TarPieceID | TarFlagList]}),
			ets:update_element(?ETS_BATTLE, EtsBattle#ets_battle.roomID, {#ets_battle.stationList, StationList2}),
			EtsBattle#ets_battle{stationList = StationList2}
	end;
onMoveResult(MoveResult, SrcStationID, TarStationID, WithFlag, EtsBattle) ->
	?ERR("onMoveResult MoveResult, SrcStationID, TarStationID, WithFlag, EtsBattle=~p", [{MoveResult, SrcStationID, TarStationID, WithFlag, EtsBattle}]),
	EtsBattle.

%%检测是否胜利
%%return false|Pos
checkWin(#ets_battle{stationList = StationList} = EtsBattle) ->
	%%当两个军旗 分别在自己一方时，自己获胜
	{StationIDList1, StationIDList2} = data_battle:get(check_win),
	%%直接检测指定ID兵站
	CheckFun = fun(StationID) ->
		%%兵站上有且仅有一个军旗
		#station{pieceID = PieceID, flagPieceList = FlagList} = lists:keyfind(StationID, #station.stationID, StationList),
		case FlagList of
			[_FlagID] ->%%上面不能再是军旗
				PieceType = element(1, battle_lib:getCfgPiece(PieceID)),
				PieceType =/= ?PIECE_LEVEL_JUN_QI;
			[] ->%%上面必须是军旗
				case PieceID of
					?UNCOVER_PIECE_ID ->
						?FALSE;%%还未翻开
					_ ->
						PieceType = element(1, battle_lib:getCfgPiece(PieceID)),
						PieceType =:= ?PIECE_LEVEL_JUN_QI
				end;
			_ -> ?FALSE
		end
	           end,
	CheckR = case lists:all(CheckFun, StationIDList1) of
		         ?TRUE ->
			         1;
		         _ ->
			         case lists:all(CheckFun, StationIDList2) of
				         ?TRUE ->
					         2;
				         _ -> ?FALSE
			         end
	         end,
	%%是否地雷已经排完
	case CheckR of
		?FALSE -> ?FALSE;
		_ ->
			case battle_lib:isMineClear(CheckR, EtsBattle) of
				?TRUE -> CheckR;
				_ -> ?FALSE
			end
	end.

onWin(0) ->%%平局
	RoomID = getRoomID(),
	EtsRoom = room_manager:getEtsRoom(RoomID),
	ets:update_element(?ETS_BATTLE, RoomID, [
		{#ets_battle.turnPos, 0},
		{#ets_battle.turnEndTime, 0},
		{#ets_battle.stationID, 0}
	]),
	%%将两个战斗玩家位置修改为正数
	RoomPlayerList1 = lists:map(
		fun(#room_player{pos = Pos} = RP) ->
			?IF(Pos =< 2, RP#room_player{pos = abs(Pos)}, RP)
		end, EtsRoom#ets_room.playerList),
	ets:update_element(?ETS_ROOM, RoomID, [
		{#ets_room.roomState, ?ROOM_STATE_IDLE},
		{#ets_room.playerList,RoomPlayerList1}
	]),
	%%广播
	role_lib:broadcastToClient(EtsRoom, #sc_battle_over{winPos = 0, playerName = "", playerHead = ""}),
	ok;
onWin(WinPos) ->
	RoomID = getRoomID(),
	EtsRoom = room_manager:getEtsRoom(RoomID),
	ets:update_element(?ETS_BATTLE, RoomID, [
		{#ets_battle.turnPos, 0},
		{#ets_battle.turnEndTime, 0},
		{#ets_battle.stationID, 0}
	]),
	%%将两个战斗玩家位置修改为正数
	RoomPlayerList1 = lists:map(
		fun(#room_player{pos = Pos} = RP) ->
			?IF(Pos =< 2, RP#room_player{pos = abs(Pos)}, RP)
		end, EtsRoom#ets_room.playerList),
	ets:update_element(?ETS_ROOM, RoomID, [
		{#ets_room.roomState, ?ROOM_STATE_IDLE},
		{#ets_room.playerList,RoomPlayerList1}
	]),
	%%广播
	#room_player{playerID = WinPlayerID} = lists:keyfind(WinPos, #room_player.pos, EtsRoom#ets_room.playerList),
	#ets_role_public{roleName = RoleName, headurl = HeadUrl} = role_lib:getRolePublic(WinPlayerID),
	role_lib:broadcastToClient(EtsRoom, #sc_battle_over{winPos = abs(WinPos), playerName = RoleName, playerHead = HeadUrl}),
	OtherPos = battle_lib:changeTurnPos(WinPos),
	#room_player{playerID = LosePlayerID} = lists:keyfind(OtherPos, #room_player.pos, EtsRoom#ets_room.playerList),
	%%给两个玩家添加 结算离线事件
	role_offline:addOfflineEvent(WinPlayerID, {?OFFLINE_EVENT_TYPE_BATTLE_END, 1}),
	role_offline:addOfflineEvent(LosePlayerID, {?OFFLINE_EVENT_TYPE_BATTLE_END, 0}),
	ok.

initEtsBattle(RoomID, InitPos, TurnEndTime) ->
	InitEtsBattle = #ets_battle{
		roomID = RoomID,
		turnPos = -InitPos,
		turnEndTime = TurnEndTime,
		stationID = 0,
		pieceIDList = data_piece:get_list(),
		stationList = initStationList(),
		deadList = {[], []},
		systemTurnCount = {0,0}
	},
	InitEtsBattle.

initStationList() ->
	StationIDList = data_station:get_list(),
	Fun = fun(StationID) ->
		%%前线、山界、行营 不放棋子
		StationType = element(1, battle_lib:getCfgStation(StationID)),
		case lists:member(StationType, [?STATION_TYPE_SHAN_JIE, ?STATION_TYPE_QIAN_XIAN, ?STATION_TYPE_XING_YING]) of
			?TRUE ->
				#station{stationID = StationID, pieceID = 0, flagPieceList = []};
			_ ->
				#station{stationID = StationID, pieceID = ?UNCOVER_PIECE_ID, flagPieceList = []}
		end
	      end,
	lists:map(Fun, StationIDList).

%%每秒心跳
secondsTick(Now) ->
	timer_wheel:plan(Now + 1, fun secondsTick/1),
	checkChangeTurn(Now),
	ok.

%%检测操作超时
checkChangeTurn(Now) ->
	try
		RoomID = getRoomID(),
		%%是否在战斗中
		EtsRoom = room_manager:getEtsRoom(RoomID),
		case EtsRoom#ets_room.roomState of
			?ROOM_STATE_BATTLE -> ok;
			_ -> throw(ok)
		end,
		EtsBattle = room_manager:getEtsBattle(RoomID),
		%%是否需要切换回合方
		case Now > EtsBattle#ets_battle.turnEndTime of
			?TRUE ->%%该切换
				ok;
			_ -> throw(ok)
		end,
		%%该切换的情况下，判断此时回合方是否已经违规多次
		Pos = EtsBattle#ets_battle.turnPos,
		TurnCount = element(abs(Pos), EtsBattle#ets_battle.systemTurnCount),
		TurnCount1 = TurnCount + 1,
		MaxTurnCount = battle_lib:getCfgBattle(system_turn_count, 5),
		OtherPos = battle_lib:changeTurnPos(Pos),
		case TurnCount1 >= MaxTurnCount of
			?TRUE ->%%已经达到最大违规次数
				%%判定当前回合方输
				onWin(OtherPos);
			_ ->
				%%增加违规次数
				SystemTurnCount1 = setelement(abs(Pos), EtsBattle#ets_battle.systemTurnCount, TurnCount1),
				%%记录该次为系统切换
				LastTurnTimeOut1 = setelement(abs(Pos), EtsBattle#ets_battle.lastTurnTimeOut, ?TRUE),
				IsLastTurnTimeOut = element(abs(OtherPos), LastTurnTimeOut1),
				TurnEndTime1 = case IsLastTurnTimeOut of
					               ?TRUE -> Now + battle_lib:getCfgBattle(punish_turn_time, 15);
					               _ -> Now + battle_lib:getCfgBattle(turn_time, 30)
				               end,
				ets:update_element(?ETS_BATTLE, RoomID, [
					{#ets_battle.turnPos, OtherPos},
					{#ets_battle.turnEndTime, TurnEndTime1},
					{#ets_battle.stationID, 0},
					{#ets_battle.systemTurnCount, SystemTurnCount1},
					{#ets_battle.lastTurnTimeOut, LastTurnTimeOut1}
				]),
				%%广播
				role_lib:broadcastToClient(EtsRoom, #sc_battle_turn{pos = abs(OtherPos), turnEndTime = TurnEndTime1}),
				ok
		end,
		ok
	catch
		ok -> ok
	end.